package com.tlgen.orm.components.rest;

import com.tlgen.orm.param.FieldParam;
import org.apache.commons.collections4.CollectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ParamExtractor {

    public static List<FieldParam> extractParams(Method method, Object[] args) {
        List<FieldParam> params = new ArrayList<>();

        // 获取方法参数信息
        Parameter[] parameters = method.getParameters();

        for (int i = 0; i < parameters.length; i++) {
            Parameter param = parameters[i];
            Object arg = args[i];

            // 处理不同类型的参数
            if (arg == null) {
                params.add(new FieldParam(null, param.getName(), null));
            } else if (isSimpleType(arg)) {
                // 基本类型或简单对象
                params.add(new FieldParam(arg.getClass(), param.getName(), arg));
            } else if (arg instanceof Map) {
                // Map 类型参数 - 保持键值对结构
                extractMapParams((Map<?, ?>) arg, param.getName(), params);
            } else if (arg instanceof Collection) {
                // 集合类型参数 - 整体作为值
                params.add(new FieldParam(arg.getClass(), param.getName(), arg));
            } else if (arg.getClass().isArray()) {
                // 数组类型参数 - 整体作为值
                params.add(new FieldParam(arg.getClass(), param.getName(), arg));
            } else {
                // 复杂对象类型 - 递归处理字段
                extractObjectParams(arg, param.getName(), params);
            }
        }

        // 处理参数名称中的点号
        if (CollectionUtils.isNotEmpty(params)) {
            params = params.stream().peek(x -> {
                if (x.getName().contains(".")) {
                    String[] split = x.getName().split("\\.");
                    x.setName(split[1]);
                }
            }).collect(Collectors.toList());
        }

        return params;
    }

    private static boolean isSimpleType(Object obj) {
        Class<?> clazz = obj.getClass();
        return clazz.isPrimitive() ||
                clazz.equals(String.class) ||
                clazz.equals(Integer.class) ||
                clazz.equals(Long.class) ||
                clazz.equals(Double.class) ||
                clazz.equals(Float.class) ||
                clazz.equals(Boolean.class) ||
                clazz.equals(Character.class) ||
                clazz.equals(Byte.class) ||
                clazz.equals(Short.class);
    }

    private static void extractMapParams(Map<?, ?> map, String prefix, List<FieldParam> params) {
        for (Map.Entry<?, ?> entry : map.entrySet()) {
            String key = entry.getKey().toString();
            Object value = entry.getValue();

            // 键为prefix.key
            String fullKey = prefix + "." + key;

            if (value == null) {
                params.add(new FieldParam(null, fullKey, null));
            } else if (isSimpleType(value)) {
                params.add(new FieldParam(value.getClass(), fullKey, value));
            } else if (value instanceof Collection || value.getClass().isArray()) {
                // 保持集合/数组整体作为值
                params.add(new FieldParam(value.getClass(), fullKey, value));
            } else {
                // 递归处理嵌套对象
                extractObjectParams(value, fullKey, params);
            }
        }
    }

    private static void extractObjectParams(Object obj, String prefix, List<FieldParam> params) {
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            try {
                field.setAccessible(true);
                Object value = field.get(obj);
                String fieldName = prefix + "." + field.getName();

                if (value == null) {
                    params.add(new FieldParam(null, fieldName, null));
                } else if (isSimpleType(value)) {
                    // 简单类型 - 直接添加
                    params.add(new FieldParam(value.getClass(), fieldName, value));
                } else if (value instanceof Collection || value.getClass().isArray()) {
                    // 集合/数组 - 整体作为值
                    params.add(new FieldParam(value.getClass(), fieldName, value));
                } else if (value instanceof Map) {
                    // Map - 递归处理
                    extractMapParams((Map<?, ?>) value, fieldName, params);
                } else {
                    // 复杂对象 - 递归处理
                    extractObjectParams(value, fieldName, params);
                }
            } catch (IllegalAccessException e) {
                // 忽略无法访问的字段
            }
        }
    }

}